﻿/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is tyzoh.jp code.
 *
 * The Initial Developer of the Original Code is Kazutaka Kurihara.
 * Portions created by the Initial Developer are Copyright (C) 2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * ***** END LICENSE BLOCK ***** */
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Net;
using System.ComponentModel;
using System.Drawing;
using System.Reflection;
using System.IO;

namespace Qurihara
{
    public class ImageDLFactory
    {
        public virtual ImageDLProxy GetImageDLProxy()
        {
            return new ImageDirectDL();
        }
    }
    public abstract class ImageDLProxy
    {
        #region somethingdownloadedhandler & arg
        public class SomethingDownloadedEventArg : AsyncCompletedEventArgs
        {
            public SomethingDownloadedEventArg(Exception error, bool cancelled,object userState, object downloadedObject) :base(error,cancelled,userState)
            {
                Something = downloadedObject;
            }
            public object Something;
        }
        public delegate void SomethingDownloadedEventHandler(object o, SomethingDownloadedEventArg e);
        #endregion

        protected static Bitmap defaultBitmap = null;
        static ImageDLProxy()
        {
            Assembly assm = Assembly.GetExecutingAssembly();
            Stream stream = assm.GetManifestResourceStream("Slide.linkmissing.png");
            Image im = System.Drawing.Image.FromStream(stream);
            defaultBitmap = new Bitmap(im);
        }
        public ImageDLProxy()
        {
            //仮イメージの表示
            SetDefaultBitmap();

        }
        public abstract void Download(string url);
        protected Bitmap bitmap;
        public Bitmap Bitmap
        {
            get { return bitmap; }
        }
        public abstract event SomethingDownloadedEventHandler ImageDownloaded;
        public void SetDefaultBitmap(){
            bitmap = defaultBitmap;
        }
    }

    public class ImageDirectDL : ImageDLProxy
    {
        public override event SomethingDownloadedEventHandler ImageDownloaded;
        //public ImageDirectDL() :base()
        //{
        //}
        public override void Download(string url)
        {
            DownloadAsync(url, DownloadFileCompleted);
        }
        protected void DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
        {
            if (!e.Cancelled && e.Error == null)
            {
                System.Net.WebClient wcl = (System.Net.WebClient)sender;
                string destPath = (string)asyncLoadingTable[wcl];
                Bitmap b = null;
                try
                {
                    b = Create(destPath);
                }
                catch
                {
                }
                if (b != null)
                {
                    bitmap = b;
                    FireImageDownloaded(b,e.Error,e.Cancelled,e.UserState);
                }
            }
            else
            {
                FireImageDownloaded(null,e.Error,e.Cancelled,e.UserState);
            }
        }
        protected void FireImageDownloaded(Bitmap b,Exception e, bool cancelled, object userState)
        {
            if (b != null)
            {
                if (ImageDownloaded != null) ImageDownloaded(this, new SomethingDownloadedEventArg(e, cancelled, userState, b));
            }
            else
            {
                if (ImageDownloaded != null) ImageDownloaded(this, new SomethingDownloadedEventArg(e, cancelled, userState, null));
            }
        }
        protected Bitmap Create(string destPath)
        {
            //解像度制限するならここ

            Bitmap bm = null;
            try
            {
                bm = new Bitmap(destPath);
            }
            catch{
            }
            return bm;
        }

        private static Hashtable asyncLoadingTable = new Hashtable();
        public static void DownloadAsync(string url, AsyncCompletedEventHandler ev)
        {
            System.Net.WebClient wcl = new System.Net.WebClient();
            string destPath = System.IO.Path.GetTempFileName();
            try
            {
                asyncLoadingTable.Add(wcl, destPath);
                if (ev != null) wcl.DownloadFileCompleted += ev;
                wcl.DownloadFileCompleted += new AsyncCompletedEventHandler(wcl_DownloadFileCompleted);
                wcl.DownloadFileAsync(new Uri(url), destPath);
            }
            catch //(System.Net.WebException e)
            {
                //WriteErrLog(url + "," + e.Message);
            }
        }
        static void wcl_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
        {
            System.Net.WebClient wcl = (System.Net.WebClient)sender;
            string destPath = (string)asyncLoadingTable[wcl];
            try
            {
                System.IO.File.Delete(destPath);
            }
            catch
            {
            }
            asyncLoadingTable.Remove(wcl);
        }
    }
}
